export const CELL_TYPES = {
    EMPTY: 0,       // 空地
    WALL: 1,        // 墙壁
    BOX: 2,         // 箱子
    TARGET: 3,      // 目标点
    PLAYER: 4,      // 玩家
    BOX_ON_TARGET: 5 // 箱子在目标点上
};

export class SokobanGame {
    constructor(levelData) {
        this.levelData = levelData;
        this.reset();
        this.isCompleted = false;
        this.lastCompletionData = null;
    }

    // 重置游戏状态
    reset() {
        this.map = JSON.parse(JSON.stringify(this.levelData.map));
        this.playerPos = { ...this.levelData.playerPos };
        this.boxes = this.levelData.boxes.map(b => ({ ...b }));
        this.targets = this.levelData.targets.map(t => ({ ...t }));
        this.moves = 0;
        this.isCompleted = false;
        this.updateMap();
    }

    // 更新地图状态
    updateMap() {
        // 重置非墙壁单元格
        for (let y = 0; y < this.map.length; y++) {
            for (let x = 0; x < this.map[y].length; x++) {
                if (this.map[y][x] !== CELL_TYPES.WALL) {
                    this.map[y][x] = CELL_TYPES.EMPTY;
                }
            }
        }

        // 标记目标点
        this.targets.forEach(target => {
            if (this.map[target.y][target.x] !== CELL_TYPES.WALL) {
                this.map[target.y][target.x] = CELL_TYPES.TARGET;
            }
        });

        // 标记箱子
        this.boxes.forEach(box => {
            const cellType = this.map[box.y][box.x];
            this.map[box.y][box.x] = cellType === CELL_TYPES.TARGET
                ? CELL_TYPES.BOX_ON_TARGET
                : CELL_TYPES.BOX;
        });

        // 标记玩家
        this.map[this.playerPos.y][this.playerPos.x] = CELL_TYPES.PLAYER;
    }

    // 移动玩家
    move(direction) {
        if (this.isCompleted) return false;

        const directions = {
            'up': { x: 0, y: -1 },
            'down': { x: 0, y: 1 },
            'left': { x: -1, y: 0 },
            'right': { x: 1, y: 0 }
        };

        const dir = directions[direction];
        if (!dir) return false;

        const newX = this.playerPos.x + dir.x;
        const newY = this.playerPos.y + dir.y;

        // 边界检查
        if (newY < 0 || newY >= this.map.length || newX < 0 || newX >= this.map[0].length) {
            return false;
        }

        const targetCell = this.map[newY][newX];

        // 碰到墙壁
        if (targetCell === CELL_TYPES.WALL) {
            return false;
        }

        // 碰到箱子
        if (targetCell === CELL_TYPES.BOX || targetCell === CELL_TYPES.BOX_ON_TARGET) {
            const boxIndex = this.boxes.findIndex(b => b.x === newX && b.y === newY);
            if (boxIndex === -1) return false;

            const nextBoxX = newX + dir.x;
            const nextBoxY = newY + dir.y;

            // 检查箱子前面是否可以移动
            if (nextBoxY < 0 || nextBoxY >= this.map.length ||
                nextBoxX < 0 || nextBoxX >= this.map[0].length) {
                return false;
            }

            const nextCell = this.map[nextBoxY][nextBoxX];
            if (nextCell === CELL_TYPES.WALL ||
                nextCell === CELL_TYPES.BOX ||
                nextCell === CELL_TYPES.BOX_ON_TARGET) {
                return false;
            }

            // 移动箱子
            this.boxes[boxIndex].x = nextBoxX;
            this.boxes[boxIndex].y = nextBoxY;
        }

        // 移动玩家
        this.playerPos.x = newX;
        this.playerPos.y = newY;
        this.moves++;

        this.updateMap();
        const justCompleted = this.checkCompletion();

        return{
            moved: true,
            levelCompleted: justCompleted  // 返回是否刚刚完成关卡
        };
    }

    // 检查是否完成
    checkCompletion() {
        const newlyCompleted = this.targets.every(target =>
            this.boxes.some(box => box.x === target.x && box.y === target.y)
        );
        // 只有当状态从未完成变为完成时返回true
        const changed = newlyCompleted && !this.isCompleted;
        this.isCompleted = newlyCompleted;

        return changed;
    }

    // 修改后的检查完成方法
    checkCompletion() {
        const newlyCompleted = this.targets.every(target =>
            this.boxes.some(box => box.x === target.x && box.y === target.y)
        );

        if (newlyCompleted && !this.isCompleted) {
            this.isCompleted = true;
            this.recordCompletion(); // 新增：记录通关数据
            return true;
        }
        return false;
    }

    // 新增：记录通关数据
    recordCompletion() {
        this.lastCompletionData = {
            levelId: this.levelData.id,
            levelName: this.levelData.name,
            moves: this.moves,
            timestamp: new Date().toISOString(),
            playerName: localStorage.getItem('playerName') || '匿名玩家'
        };
        this.saveToLeaderboard();
    }

    // 新增：保存到排行榜
    saveToLeaderboard() {
        const leaderboard = JSON.parse(localStorage.getItem('sokobanLeaderboard') || '[]');

        // 只保留每个玩家每个关卡的最好成绩
        const existingIndex = leaderboard.findIndex(entry =>
            entry.levelId === this.lastCompletionData.levelId &&
            entry.playerName === this.lastCompletionData.playerName
        );

        if (existingIndex >= 0) {
            // 如果已有记录，只更新步数更少的
            if (this.lastCompletionData.moves < leaderboard[existingIndex].moves) {
                leaderboard[existingIndex] = this.lastCompletionData;
            }
        } else {
            leaderboard.push(this.lastCompletionData);
        }

        // 按步数排序
        leaderboard.sort((a, b) => a.moves - b.moves);
        localStorage.setItem('sokobanLeaderboard', JSON.stringify(leaderboard));
    }
}
